package net.pulseproject.router.modules.useable;

import java.util.Collection;
import java.util.HashSet;

import javax.sound.midi.ShortMessage;

import net.pulseproject.commons.midi.Receivable;
import net.pulseproject.commons.midi.Transmitable;
import net.pulseproject.commons.midi.entity.MidiSocket;
import net.pulseproject.router.modules.MidiModule;
import net.pulseproject.router.modules.misc.MidiReceiverModuleListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MidiReceiverModule extends MidiModule implements Receivable {

	private static final Log LOG = LogFactory.getLog(MidiReceiverModule.class);
	
	private final Collection<MidiReceiverModuleListener> listeners = new HashSet<MidiReceiverModuleListener>();
	
	
	public MidiReceiverModule(final String id, final MidiSocket socket) {
		super(id, socket);
	}
	
	@Override
	public final void receive(final ShortMessage message, final Transmitable transmitable) {
		LOG.debug("receive(message, transmitable)");
		this.broadcast(message, transmitable);
	}
	
	private void broadcast(final ShortMessage message, final Transmitable transmitable) {
		for (final MidiReceiverModuleListener listener : this.listeners) {
			listener.onMessageReceived(message, transmitable, this);
		}
	}
	
	public final void addListener(final MidiReceiverModuleListener listener) {
		if(listener == null) { throw new IllegalArgumentException("listener == null"); }
		
		final boolean wasChanged = this.listeners.add(listener);
		
		if(wasChanged == false) {
			throw new RuntimeException("Listener [" + listener + "] already registered!");
		}
	}

	@Override
	public final String toString() {
		return "MidiReceiverModule[id=" + this.getId() + ", socket=" + this.getSocket() + ", " +
				"listeners.size=" + this.listeners.size() + "]";
	}

}
